import QtQuick
import QtQuickRO


/*
*玩家控制器负责接收输入设备的指令并用于操控角色
*一个角色在没有被任何控制器操作时原则上是不会自己动起来的
*控制器可以分为玩家控制器(PlayerController)和ai控制器
*玩家控制器能够接收来自物理设备的输入（有输入组件），而ai控制器没有
*玩家控制器本身是个同步对象，在服务端和客户端都会创建以实现将客户端的输入操作上传到服务端。
*为了防止有玩家操控别人的控制器，建议将控制器设置为仅在玩家所在主机和服务端主机创建。
*/

Item{
    id:root

    //当前正在操控的物体
    property alias pawn:shared.pawn

    //操控对象失败了，msg为失败原因。这个信号仅会在服务端发射
    signal possessFailed(msg:string)

    ROSharedObject{
        id:shared

        property Pawn pawn
    }

    RORPC{
        id:rpc

        function setPawnProperty(name,value){
            if(pawn)
            {
                pawn[name] = value
            }
        }

        function invokePawnMethod(name,args){
            if(pawn)
            {
                pawn[name](...args)
            }
        }

        function setProperty(name,value){
            root[name] = value
        }

        function invokeMethod(name,args){
            root[name](...args)
        }

        function possess(pawn){
            if(pawn.controller)
            {
                possessFailed("操控失败，目标对象正被其它控制器操控")
                return
            }

            if(root.pawn)//如果控制器原本已经控制了一个对象，那么取消对该对象的操控
            {
                root.pawn.controller = null
            }
            //操控新对象
            root.pawn = pawn
            if(root.pawn)
            {
                root.pawn.controller = root
            }
        }
    }

    //操控目标对象,pawn传入null时为取消对目标的操控
    function possess(pawn){
        //将指令上传到服务端
        rpc.call("possess",[pawn])
    }

    //从服务端设置操控目标的属性
    function setPawnProperty(name,value){
        rpc.call("setPawnProperty",[name,value])
    }

    //从服务端调用操控目标的方法
    function invokePawnMethod(name,args){
        rpc.call("invokePawnMethod",[name,args])
    }

    //从服务端设置属性
    function setProperty(name,value){
        rpc.call("setProperty",[name,value])
    }

    //从服务端调用方法
    function invokeMethod(name,args){
        rpc.call("invokeMethod",[name,args])
    }
}
